package view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;

import javax.swing.JList;
import javax.swing.JPanel;

import javax.swing.ListSelectionModel;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import javax.swing.text.View;

import view.NavigationView.NavigationItemModel;

import net.miginfocom.swing.MigLayout;

/**
 * Left navigation area for the application
 * 
 * @author MUSAB
 * @since May, 2013
 * @version $Revision: 1.0 $
 */
public class NavigationView extends JPanel {

	/**
	 * Model for the folder navigation list
	 * 
	 * @author MUSAB
	 * @since May, 2013
	 * @version $Revision: 1.0 $
	 */
	class NavigationItemModel {

		int level;
		int key;
		String value;
		int emailCount;

		/**
		 * Navigation item model constructor
		 * 
		 * @param level
		 * @param key
		 * @param value
		 * @param emailCount
		 */
		public NavigationItemModel(int level, int key, String value,
				int emailCount) {
			this.key = key;
			this.value = value;
			this.level = level;
			this.emailCount = emailCount;
		}

		/**
		 * converts the instance to a string
		 * 
		 * 
		 * @return String a string representation of the current instance
		 */
		public String toString() {

			String ec = "";
			if (emailCount > 0)
				ec = " (" + emailCount + ")";

			if (level == 0) {
				return "" + value + ec;
			} else {
				String toReturn = "";
				for (int i = 0; i < level; i++) {
					toReturn = toReturn + "   ";
				}
				return toReturn + "L " + value + ec;
			}
		}

		/**
		 * a getter for the name
		 * 
		 * 
		 * @return String the name for the item
		 */
		public String getName() {
			return value;
		}
	}

	// Labels
	private JLabel connectionStatus;
	
	// Network view
	private JTextPane notifications;
	
	// Buttons
	private JButton composeBtn, meetingsBtn, tokenBtn, templatesBtn;

	// List of folders to be shown
	private DefaultListModel<NavigationItemModel> folders;

	// JList to show list of folders
	private JList foldersList;

	/**
	 * Constructor
	 * 
	 * 
	 * @param migLayout
	 *            migLayout the layout type used
	 */
	public NavigationView(MigLayout migLayout) {

		super(migLayout);

		// init and add components
		composeBtn = new JButton("Compose mail",
				IconsManager.getImageIcon("small/mail-plus.png"));

		meetingsBtn = new JButton("Meetings...");
		templatesBtn = new JButton("Templates...");
		tokenBtn = new JButton("Tokens...");

		this.add(composeBtn, "wrap, width 150, height 50");

		folders = new DefaultListModel<NavigationItemModel>();
		foldersList = new JList<NavigationItemModel>(folders);
		foldersList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		this.add(foldersList, "grow, wrap");
		
		connectionStatus = new JLabel();
		this.add(new JLabel("Status: "), "split, gaptop 10");
		this.add(connectionStatus, "wrap");

		notifications = new JTextPane();
		notifications.getCaret().setVisible(false);
		notifications.setEditable(false);
		notifications.setBackground(new Color(0xF2F6F7));
		DefaultCaret caret = (DefaultCaret)notifications.getCaret();
		caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
		
		JScrollPane networkLogScroller = new JScrollPane(notifications);
		networkLogScroller.setBorder(BorderFactory.createEmptyBorder());
		networkLogScroller.getVerticalScrollBar().setPreferredSize(new Dimension(10, 0));
		
		this.add(new JLabel("Notifications:"), "wrap, gaptop 10");
		
		this.add(networkLogScroller, "growx, width 150, height 100:250:400");
		
		setConnectionStatus(false);
	}

	/**
	 * a getter that returns the compose button
	 * 
	 * 
	 * @return JButton composeBtn
	 */
	public JButton getComposeBtn() {
		return composeBtn;
	}

	/**
	 * a getter that returns the meeting button
	 * 
	 * 
	 * @return JButton meetingsBtn
	 */
	public JButton getMeetingBtn() {
		return meetingsBtn;
	}

	/**
	 * a getter that returns the default list of folders
	 * 
	 * 
	 * @return DefaultListModel the folders
	 */
	public DefaultListModel getFolders() {
		return folders;
	}

	/**
	 * a getter for the actual list of folders
	 * 
	 * 
	 * @return JList the actual folders List
	 */
	public JList getFoldersList() {
		return foldersList;
	}

	/**
	 * a method that activates a new compose message window
	 * 
	 * @param isNew
	 *            boolean
	 * @param from
	 *            String
	 * @param subject
	 *            String
	 */
	public void createNewComposeWindow(boolean isNew, String from,
			String subject) {
		new ComposeMailView(isNew, from, subject);
	}

	/**
	 * a method that sets the current selection of an element
	 * 
	 * @param name
	 *            String
	 */
	public void setCurrentSelection(String name) {
		for (int i = 0; i < folders.size(); i++) {
			if (folders.elementAt(i).value.trim().equalsIgnoreCase(name)) {
				foldersList.setSelectedIndex(i);
				return;
			}
		}
	}

	/**
	 * Adds a new entry to the list
	 * 
	 * @param level
	 *            int
	 * @param id
	 *            int
	 * @param name
	 *            String
	 * @param emailCount
	 *            int
	 */
	public void addNewFolder(int level, int id, String name, int emailCount) {
		folders.addElement(new NavigationItemModel(level, id, name, emailCount));
	}

	/**
	 * Returns the name of a folder at a given index
	 * 
	 * 
	 * 
	 * @param index
	 *            int
	 * @return String the name of the folder
	 */
	public String getFolderNameAt(int index) {
		return folders.get(index).value;
	}

	/**
	 * Returns the id of a folder at a given index
	 * 
	 * 
	 * 
	 * @param index
	 *            int
	 * @return int the folder id
	 */
	public int getFolderIdAt(int index) {
		return folders.get(index).key;
	}

	/**
	 * Getter for the manage tokens button
	 * 
	 * @return JButton
	 */
	public JButton getTokensBtn() {
		return tokenBtn;
	}

	/**
	 * Getter for the manage templates button
	 * 
	 * @return JButton
	 */
	public JButton getTemplatesBtn() {
		return templatesBtn;
	}

	/**
	 * Prints a message to the network log
	 * 
	 * @param messageType Type of message (warning, error, success, normal)
	 * @param message The message to be printed
	 * @throws BadLocationException 
	 */
	public void notify(String messageType, String message) {
		
		Style normal = notifications.addStyle("warning", null);
		Style warning = notifications.addStyle("normal", null);
		Style error = notifications.addStyle("error", null);
		Style success = notifications.addStyle("success", null);
		
		notifications.setFont(new Font("Arial", Font.PLAIN, 11));
		
		StyleConstants.setForeground(normal, ViewHelpers.mutedTextColor);
		StyleConstants.setForeground(warning, ViewHelpers.warningTextColor);
		StyleConstants.setForeground(error, ViewHelpers.errorTextColor);
		StyleConstants.setForeground(success, ViewHelpers.successTextColor);
		
		
		StyledDocument doc = notifications.getStyledDocument();
		
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		try {
			doc.insertString(doc.getLength(), "\n------ " + df.format(new Date()) + ":\n", normal);
		} catch (BadLocationException e1) {
			e1.printStackTrace();
		}
		
		switch(messageType){
		
		case "normal" : try {
				doc.insertString(doc.getLength(), message, normal);
			} catch (BadLocationException e) {
				e.printStackTrace();
			} break;
		case "warning" : try {
				doc.insertString(doc.getLength(), message, warning);
			} catch (BadLocationException e) {
				e.printStackTrace();
			} break;
		case "error" : try {
				doc.insertString(doc.getLength(), message, error);
			} catch (BadLocationException e) {
				e.printStackTrace();
			} break;
		case "success" : try {
				doc.insertString(doc.getLength(), message + "\n", success);
			} catch (BadLocationException e) {
				e.printStackTrace();
			} break;
		default : try {
				doc.insertString(doc.getLength(), message + "\n", normal);
			} catch (BadLocationException e) {
				e.printStackTrace();
			} break;
		}
	}
	
	/**
	 * Sets the connection status to disconnected or connected
	 * @param status
	 */
	public void setConnectionStatus(boolean connected){
		
		if (connected){
			connectionStatus.setText("Connected");
			connectionStatus.setForeground(ViewHelpers.successTextColor);
		} else {
			connectionStatus.setText("Disconnected");
			connectionStatus.setForeground(ViewHelpers.errorTextColor);
		}
	}

}

